<?php

namespace Dongasai\WkProtoPhp\Enums;

/**
 * 帧类型枚举
 * 使用PHP 8枚举语法
 */
enum FrameType: int
{
    case UNKNOWN = 0;    // 保留位
    case CONNECT = 1;    // 客户端请求连接到服务器(c2s)
    case CONNACK = 2;    // 服务端收到连接请求后确认的报文(s2c)
    case SEND = 3;       // 发送消息(c2s)
    case SENDACK = 4;   // 收到消息确认的报文(s2c)
    case RECV = 5;      // 收取消息(s2c)
    case RECVACK = 6;   // 收取消息确认(c2s)
    case PING = 7;      // ping请求
    case PONG = 8;      // 对ping请求的相应
    case DISCONNECT = 9; // 请求断开连接
    case SUB = 10;      // 订阅
    case SUBACK = 11;   // 订阅确认
    case EVENT = 12;    // 事件

    /**
     * 获取帧类型的字符串表示
     */
    public function toString(): string
    {
        return $this->name;
    }

    /**
     * 从值创建枚举实例
     */
    public static function fromValue(int $value): self
    {
        return self::from($value);
    }

    /**
     * 检查是否为连接相关帧类型
     */
    public function isConnectionType(): bool
    {
        return in_array($this, [self::CONNECT, self::CONNACK, self::DISCONNECT]);
    }

    /**
     * 检查是否为消息相关帧类型
     */
    public function isMessageType(): bool
    {
        return in_array($this, [self::SEND, self::SENDACK, self::RECV, self::RECVACK]);
    }

    /**
     * 检查是否为心跳相关帧类型
     */
    public function isHeartbeatType(): bool
    {
        return in_array($this, [self::PING, self::PONG]);
    }

    /**
     * 检查是否为订阅相关帧类型
     */
    public function isSubscriptionType(): bool
    {
        return in_array($this, [self::SUB, self::SUBACK]);
    }

    /**
     * 检查是否为客户端到服务器的帧类型
     */
    public function isClientToServer(): bool
    {
        return in_array($this, [self::CONNECT, self::SEND, self::RECVACK, self::PING, self::DISCONNECT, self::SUB]);
    }

    /**
     * 检查是否为服务器到客户端的帧类型
     */
    public function isServerToClient(): bool
    {
        return in_array($this, [self::CONNACK, self::SENDACK, self::RECV, self::PONG, self::SUBACK, self::EVENT]);
    }

    /**
     * 获取帧类型描述
     */
    public function getDescription(): string
    {
        return match ($this) {
            self::UNKNOWN => '未知类型',
            self::CONNECT => '连接请求',
            self::CONNACK => '连接确认',
            self::SEND => '发送消息',
            self::SENDACK => '发送确认',
            self::RECV => '接收消息',
            self::RECVACK => '接收确认',
            self::PING => '心跳请求',
            self::PONG => '心跳响应',
            self::DISCONNECT => '断开连接',
            self::SUB => '订阅请求',
            self::SUBACK => '订阅确认',
            self::EVENT => '事件通知',
        };
    }

    /**
     * 获取对应的包类名
     */
    public function getPacketClassName(): string
    {
        return match ($this) {
            self::CONNECT => 'ConnectPacket',
            self::CONNACK => 'ConnackPacket',
            self::SEND => 'SendPacket',
            self::SENDACK => 'SendackPacket',
            self::RECV => 'RecvPacket',
            self::RECVACK => 'RecvackPacket',
            self::PING => 'PingPacket',
            self::PONG => 'PongPacket',
            self::DISCONNECT => 'DisconnectPacket',
            default => 'UnknownPacket',
        };
    }
}